package com.weareint.common.config;

import com.weareint.common.TokenProvider;
import com.weareint.common.interceptors.AuthenticationInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.servlet.config.annotation.*;

import java.util.ArrayList;

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

    @Autowired
    private TokenProvider tokenProvider;

    @Autowired
    private ApplicationProperties applicationProperties;

    /**
     * <pre>
     *     添加拦截器，只要用于权限拦截
     * </pre>
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        ApplicationProperties.AuthConfig authConfig = applicationProperties.getAuthConfig();
        ApplicationProperties.Swagger2 swagger2 = applicationProperties.getSwagger2();
        if (null == authConfig.getWhites()){
            authConfig.setWhites(new ArrayList<>());
        }
        // 当Swagger启用时，把Swagger相关的URL加入权限白名单
        if (swagger2.isEnable() && null != swagger2.getUrls() && !swagger2.getUrls().isEmpty()){
            authConfig.getWhites().addAll(swagger2.getUrls());
        }
        registry.addInterceptor(authenticationInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns(authConfig.getWhites());
    }

    /**
     * <pre>
     *     为Swagger配置静态资源
     * </pre>
     *
     * @param registry
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        ApplicationProperties.Swagger2 swagger2 = applicationProperties.getSwagger2();
        if (swagger2.isEnable()){
            registry.addResourceHandler("/swagger-ui/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
            registry.addResourceHandler("/webjars/**")
                    .addResourceLocations("classpath:/META-INF/resources/webjars/");
            registry.addResourceHandler("/**")
                    .addResourceLocations("classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/", "/");
        }
    }

    /**
     * <pre>
     *     为Swagger配置访问 http://localhost:8080/swagger-ui 或 http://localhost:8080/swagger-ui/ 时的重定向
     * </pre>
     *
     * @param registry
     */
    @Override
    protected void addViewControllers(ViewControllerRegistry registry) {
        ApplicationProperties.Swagger2 swagger2 = applicationProperties.getSwagger2();
        if (swagger2.isEnable()){
            registry.addRedirectViewController("/swagger-ui", "/swagger-ui/index.html");
            registry.addRedirectViewController("/swagger-ui/", "/swagger-ui/index.html");
        }
    }

    /**
     * <pre>
     *     配置跨域访问
     * </pre>
     *
     * @param registry
     */
    @Override
    protected void addCorsMappings(CorsRegistry registry) {
        CorsConfiguration cors = applicationProperties.getCors();
        if (null != cors) {
            // 所以请求都可以跨域
            CorsRegistration registration = registry.addMapping("/**");
            if (null != cors.getAllowCredentials()){
                registration.allowCredentials(cors.getAllowCredentials());
            }
            if (null != cors.getAllowedHeaders()){
                registration.allowedHeaders(cors.getAllowedHeaders().toArray(new String[]{}));
            }
            if (null != cors.getAllowedMethods()){
                registration.allowedMethods(cors.getAllowedMethods().toArray(new String[]{}));
            }
            if (null != cors.getAllowedOriginPatterns()){
                registration.allowedOriginPatterns(cors.getAllowedOriginPatterns().toArray(new String[]{}));
            }
            if (null != cors.getAllowedOrigins()){
                registration.allowedOrigins(cors.getAllowedOrigins().toArray(new String[]{}));
            }
            if (null != cors.getExposedHeaders()){
                registration.exposedHeaders(cors.getExposedHeaders().toArray(new String[]{}));
            }
            if (null != cors.getMaxAge()){
                registration.maxAge(cors.getMaxAge());
            }
        }

    }

    /**
     * <pre>
     *     权限拦截器
     * </pre>
     *
     * @return
     */
    @Bean
    public AuthenticationInterceptor authenticationInterceptor() {
        return new AuthenticationInterceptor(tokenProvider);
    }
}
